import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { List } from '../_model/list';
import { ListOrigin } from '../_model/listOrigin';
import { Task } from '../_model/task';
import { Functions } from '../functions';
import { NewListDto } from '../_dtos/newListDto';
import { RenameTitleDto } from '../_dtos/renameTitleDto';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import 'string.prototype.at';

@Injectable()
export class ListService {
  lists: List[];
  headers: Headers;
  constructor(
    private _http: Http,
    private _funcs: Functions) {
    const uid = this._funcs.getCurrentUser().id;
    this.InitLists(uid);
  }

  InitLists(uid: string) {
    this._http.get(`api/list/${uid}`, this._funcs.getRequestOptions())
      .map(response => response.json() as ListOrigin[])
      .catch(this._funcs.handleHttpError)
      .subscribe(data => {
        const origin = data as ListOrigin[];
        this.lists = origin.map(item => {
          const isDoneArray = item.tasks.filter(u => !u.isDone);
          const listNew: List = { ...item, 'number': isDoneArray.length };
          return listNew;
        });
      });
  }

  getTasksByListId(id: string): Task[] {
    return this.lists && this.lists.find(u => u.id === id).tasks;
  }

  getListTitle(lid: string): Observable<string> {
    const title = (this.lists && this.combineTitle(lid)) || null;
    const ob = new Observable<string>(observer => {
      observer.next(title);
      observer.complete();
    });
    return ob;
  }

  // 返回组合后的标题（如果存在自定义的icon那么返回icon+title）
  combineTitle(lid): string {
    const list = this.lists.find(u => u.id === lid);
    if (this._funcs.isDefaultIcon(list.icon)) {
      return list.title;
    }
    return list.icon + list.title;
  }

  getTodayTasks(): Task[] {
    const tasks: Task[] = [];
    this.lists.forEach(item => {
      const res = item.tasks.filter(u => u.today);
      tasks.push(...res);
    });
    return tasks;
  }

  addNewList(list: NewListDto): Observable<List> {
    return this._http.post(`api/list`, list, this._funcs.getRequestOptions())
      .map(response => response.json() as List);
  }

  rename(payload: RenameTitleDto): void {
    // * 修改远程数据
    // tslint:disable-next-line:max-line-length
    const regex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*/g;
    const char = (payload.title as any).at(0);  // to solve the ts lint
    if (regex.test(char)) {
      // * 如果第一个字符是emoji
      payload.title = payload.title.substring(2);
      payload.icon = char;
    }
    this._http.put(
      'api/list/title',
      payload,
      this._funcs.getRequestOptions()
    ).subscribe();
    // * 修改本地数据
    const list = this.lists.find(u => u.id === payload.id);
    list.title = payload.title;
    if (payload.icon) {
      list.icon = payload.icon;
    }
  }

  deleteList(lid: string): Observable<any> {
    return this._http.delete(
      `api/list/${lid}`,
      this._funcs.getRequestOptions()
    ).catch(this._funcs.handleHttpError);
  }

}
